package earogya.ehr.patient_details.ws;

import java.io.IOException;

import org.hibernate.HibernateException;

import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.model.v251.segment.*;
import ca.uhn.hl7v2.model.v251.message.*;
import ca.uhn.hl7v2.parser.EncodingNotSupportedException;
import ca.uhn.hl7v2.parser.PipeParser;
import earogya.ehr.patient_details.messages.*;


/***
 * 
 * Message handler for the patient details management
 * 
 * @author Ureka
 *
 */
public class HL7MessageHandler {

	/**
	 * 
	 * Parse the message and generate the acknowledgement
	 * 
	 * @param message
	 * @return
	 */
	public String parser(String message){
		PipeParser p=new PipeParser();
		String ack=null;
		 Message hapiMsg;
		 try {
			 hapiMsg = p.parse(message);
		 	 MSH mshSegment=(MSH)hapiMsg.get("MSH");
		 	 String msgType=mshSegment.getMessageType().getMessageCode().getValue();
			 String msgTrigger = mshSegment.getMessageType().getTriggerEvent().getValue();
			 ack=identifyMessage(msgType, msgTrigger, hapiMsg);
		} catch (EncodingNotSupportedException e) {
			 e.printStackTrace();
		 } catch (HL7Exception e) {
			 e.printStackTrace();
		 } catch (HibernateException e) {
			 e.printStackTrace();
		} catch (IOException e) {
			 e.printStackTrace(); 
		}	
		 return ack;
	}
	
	/**
	 * 
	 * Identify the message type and send it to the relevant trigger
	 * 
	 * @param messageCode
	 * @param triggerEvent
	 * @param hapiMsg
	 * @return the acknowledgement
	 * @throws HibernateException
	 * @throws IOException
	 * @throws HL7Exception
	 */
	private String identifyMessage(String messageCode, String triggerEvent, Message hapiMsg) throws HibernateException, IOException, HL7Exception{
		String ack=null;
		if(messageCode.equals("ADT")){
			ack=this.identifyTriggerEventForADT(triggerEvent, hapiMsg);
		}else if(messageCode.equals("ADR")){
			this.identifyTriggerEventForADR(triggerEvent);
		}else if(messageCode.equals("ACK")){
			this.identifyTriggerEventForACK(triggerEvent);
		}else if(messageCode.equals("ORU")){
			this.identifyTriggerEventForORU(triggerEvent);
		}else if(messageCode.equals("QRY")){
			ack=this.identifyTriggerEventForQRY(triggerEvent,hapiMsg);
		}else{
			System.out.println("Unexpected trigger event");
		}
		return ack;
	}
	
	
	/**
	 * 
	 * Identify the messages of ADT type and invoke the relevant message handler
	 * 
	 * @param triggerEvent
	 * @param hapiMsg
	 * @return acknowledgement
	 * @throws HibernateException
	 * @throws IOException
	 * @throws HL7Exception
	 */
	private String identifyTriggerEventForADT(String triggerEvent, Message hapiMsg) throws HibernateException, IOException, HL7Exception{
		String ack=null;
		if(triggerEvent.equals("A04")){
			 ADT_A01 adtMsg = (ADT_A01)hapiMsg;
			 ADT_A04_Handler handler=new ADT_A04_Handler(adtMsg);
			 ack=handler.manageMessage();
		}
		else if(triggerEvent.equals("A08")){
			ADT_A01 adtMsg = (ADT_A01)hapiMsg;
			ADT_A08_Handler handler=new ADT_A08_Handler(adtMsg);
			ack=handler.manageMessage();
		}
		
		else if(triggerEvent.equals("A60")){
			ADT_A60 adtMsg = (ADT_A60)hapiMsg;
			ADT_A60_Handler handler=new ADT_A60_Handler(adtMsg);
			ack=handler.manageMessage();
		}
		else if(triggerEvent.equals("A34")){
			ADT_A30 adtMsg = (ADT_A30)hapiMsg;
			ADT_A34_Handler handler=new ADT_A34_Handler(adtMsg);
			ack=handler.manageMessage();
		}
		else{
			System.out.println("Unexpected message");
		}
		return ack;
	}
	
	private void identifyTriggerEventForACK(String triggerEvent){
		
	}
	
	private void identifyTriggerEventForADR(String triggerEvent){
		
	}
	
	private void identifyTriggerEventForORU(String triggerEvent){
		
	}
	
	
	/**
	 * 
	 * Identify the messages of QRY type and invoke the relevant message handler
	 * 
	 * @param triggerEvent
	 * @param hapiMsg
	 * @return acknowledgement
	 * @throws HibernateException
	 * @throws IOException
	 * @throws HL7Exception
	 */
	private String identifyTriggerEventForQRY(String triggerEvent,Message hapiMsg) throws HibernateException, IOException, HL7Exception{
		String ack=null;
		if(triggerEvent.equals("A19")){
			 QRY_A19 qryMsg = (QRY_A19)hapiMsg;
			 QRY_A19_Handler handler=new QRY_A19_Handler(qryMsg);
			 ack=handler.manageMessage();
		}
		return ack;
	}
}
